package com.archerdu.apply.controller.admin;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.archerdu.apply.model.Function;
import com.archerdu.apply.model.Menu;
import com.archerdu.apply.model.Role;
import com.archerdu.apply.model.User;
import com.archerdu.apply.service.FunctionManager;
import com.archerdu.apply.service.MenuManager;
import com.archerdu.apply.service.RoleManager;
import com.archerdu.base.controller.BaseController;
import com.archerdu.base.dao.IPage;
import com.archerdu.commons.constant.DataConstant;

/**
 * 
 * @projectName: springDemo
 * @package: com.archerdu.apply.controller.admin
 * @className: RoleController
 * @description: 角色管理
 * @author: archer du
 * @createDate: 2013-8-9 下午4:57:38
 * @updateUser: dxf
 * @updateDate: 2013-8-9 下午4:57:38
 * @updateRemark: 新建
 * @version: 0.0.1
 */
@Controller
@Scope("prototype")
@RequestMapping("/admin/role")
public class RoleController extends BaseController {

    private static final long serialVersionUID = 5676515795441813282L;

    private RoleManager       roleManager;

    private MenuManager       menuManager;

    private FunctionManager   functionManager;

    private Role              role;

    @RequestMapping(value = "/add")
    public ModelAndView add(HttpServletRequest requ, RoleController rc) {
        role = rc.getRole();
        ModelAndView mv = new ModelAndView();
        mv.setViewName("admin/role/add");
        if ("post".equalsIgnoreCase(requ.getMethod())) {
            try {
                role.setCreateUser(((User) requ.getSession().getAttribute(DataConstant.SESSION_SYS_USER)).getId());
                role.setCreatetime(getSqlDate());
                roleManager.add(role);
                addMessage(DataConstant.COMMON_ADD_SUCCESS);
            } catch (Exception e) {
                addMessage(DataConstant.COMMON_ADD_FAILED);
                logger.error(e.getMessage(), e);
            }
        }
        return mv;
    }

    /**
     * 角色编辑
     * 
     * @param requ
     * @param role
     * @return
     */
    @RequestMapping(value = "/edit")
    public ModelAndView edit(HttpServletRequest requ, RoleController mc) {

        logger.debug("role.id is " + mc.getRole().getId());
        role = mc.getRole();

        if ("get".equalsIgnoreCase(requ.getMethod())) {
            if (!StringUtils.isEmpty(role.getId())) {
                role = roleManager.get(role.getId());
            }
        } else {
            role.setUpdateUser(((User) requ.getSession().getAttribute((DataConstant.SESSION_SYS_USER))).getId());
            role.setUpdatetime(getSqlDate());
            try {
                roleManager.modify(role);
                role = roleManager.get(role.getId());
                addMessage(DataConstant.COMMON_EDIT_SUCCESS);
            } catch (Exception e) {
                addMessage(DataConstant.COMMON_EDIT_FAILED);
                logger.error(e.getMessage(), e);
            }
        }

        ModelAndView mav = new ModelAndView();
        mav.addObject(getMessage());
        mav.addObject(role).setViewName("admin/role/edit");
        return mav;
    }
    
    /**
     * 删除角色
     * 
     * @param requ
     * @param uc
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/remove")
    public ModelAndView remove(HttpServletRequest requ, RoleController rc, Integer pageNo, Integer pageSize) {
        role = rc.getRole();
        if (null != role && null != role.getId()) {
            role = roleManager.get(role.getId());
            role.setUseFlag(DataConstant.COMMON_USE_FLAG_NO);
            // TODO 有用户不能删除角色
            try {
                roleManager.modify(role);
                addMessage(DataConstant.COMMON_DEL_SUCCESS);
            } catch (Exception e) {
                addMessage(DataConstant.COMMON_DEL_FAILED);
                logger.error(e.getMessage(), e);
            }
        }

        ModelAndView mav = page(requ, rc, pageNo, pageSize);
        mav.addObject(getMessage());
        return mav;
    }

    /**
     * 分页查询
     * 
     * @param requ
     * @param rc
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/page")
    public ModelAndView page(HttpServletRequest requ, RoleController rc, Integer pageNo, Integer pageSize) {

        if (null == rc.getRole()) {
            role = new Role();
        } else {
            role = rc.getRole();
        }

        if (null == pageNo || null == pageSize) {
            pageNo = 1;
            pageSize = 20;
        }
        logger.debug("userManager is " + roleManager);
        
        role.setUseFlag(DataConstant.COMMON_USE_FLAG_YES);
        IPage<Role> page = roleManager.pageSearch(role, pageNo, pageSize);

        ModelAndView mav = new ModelAndView();
        mav.addObject(page).setViewName("admin/role/page");
        return mav;
    }

    /**
     * 关联目录到角色
     * 
     * @param request
     * @param rc
     * @param menuIds
     * @return
     */
    @RequestMapping("/menu")
    public ModelAndView menu(HttpServletRequest request, RoleController rc, Integer[] menuIds) {
        role = rc.getRole();
        ModelAndView mv = new ModelAndView();
        logger.debug("--- menuIds is " + menuIds);
        if ("post".equalsIgnoreCase(request.getMethod()) && null != menuIds && null != role && null != role.getId()) {
            logger.info("--- start to load menus");

            role = roleManager.get(role.getId());

            Set<Menu> menus = new HashSet<Menu>();
            for (Integer i : menuIds) {
                menus.add(menuManager.get(i));
            }
            role.setMenus(menus);
            logger.info("start to add menus to role");
            try {
                roleManager.modify(role);
                this.addMessage(DataConstant.COMMON_ADD_SUCCESS);
                logger.info("success to add role's menus");

            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                this.addMessage(DataConstant.COMMON_ADD_FAILED);
                logger.info("failed to add role's menus");
            }
        }
        // 获取完整目录列表
        if (null != role && null != role.getId()) {

            role = roleManager.get(role.getId());
            Menu menu = new Menu();
            menu.setId(0);
            JSONArray jsonObject = menuManager.loadJsonObject(menu);

            checkedMenu(jsonObject);

            String menuJson = jsonObject.toString();
            mv.addObject(role);
            mv.addObject(menuJson);
        }
        mv.addObject(getMessage());
        return mv;
    }

    /**
     * 关联功能到角色
     * 
     * @param request
     * @param rc
     * @param functionIds
     * @return
     */
    @RequestMapping("/function")
    public ModelAndView function(HttpServletRequest request, RoleController rc, Integer[] functionIds) {
        role = rc.getRole();
        ModelAndView mv = new ModelAndView();

        if ("post".equalsIgnoreCase(request.getMethod()) && null != role && null != role.getId()) {
            role = roleManager.get(role.getId());

            Set<Function> functions = new HashSet<Function>();

            if (null != functionIds) {
                for (Integer i : functionIds) {
                    functions.add(functionManager.get(i));
                }
            }
            role.setFunctions(functions);
            logger.info("--- start to add functions");
            try {
                roleManager.modify(role);
                this.addMessage(DataConstant.COMMON_ADD_SUCCESS);
                logger.info("success to add role's functions");

            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                this.addMessage(DataConstant.COMMON_ADD_FAILED);
                logger.info("failed to add role's functions");
            }
        }
        // 获取完整功能列表
        if (null != role && null != role.getId()) {

            role = roleManager.get(role.getId());
            Function function = new Function();
            function.setId(0);
            JSONArray jsonObject = functionManager.loadJsonObject(function);

            checkedFunction(jsonObject);

            mv.addObject(role);
            mv.addObject("functionJson", jsonObject.toString());
        }
        mv.addObject(getMessage());
        return mv;
    }

    /**
     * 标注被选中的目录选项
     * 
     * @param ja
     */
    @SuppressWarnings("unchecked")
    private void checkedMenu(JSONArray ja) {

        Iterator<JSONObject> it = ja.iterator();

        while (it.hasNext()) {
            JSONObject jsonO = it.next();

            for (Menu ro : role.getMenus()) {
                if (jsonO.getInt("id") == ro.getId()) {
                    // ro.setChecked("checked=\"checked\"");
                    // struts2标签属性
                    jsonO.element("checked", "true");
                }
            }
            JSONArray jsonObject = jsonO.getJSONArray("children");
            if (jsonObject.size() > 0) {
                checkedMenu(jsonObject);
            }
        }
    }

    /**
     * 标注被选中的功能选项
     * 
     * @param ja
     */
    @SuppressWarnings({ "unchecked" })
    private void checkedFunction(JSONArray ja) {

        Iterator<JSONObject> it = ja.iterator();

        while (it.hasNext()) {
            JSONObject jsonO = it.next();

            for (Function ro : role.getFunctions()) {
                if (jsonO.getInt("id") == ro.getId()) {
                    // ro.setChecked("checked=\"checked\"");
                    // struts2标签属性
                    jsonO.element("checked", "true");
                }
            }
            JSONArray jsonObject = jsonO.getJSONArray("children");
            if (jsonObject.size() > 0) {
                checkedFunction(jsonObject);
            }
        }
    }

    public RoleManager getRoleManager() {
        return roleManager;
    }

    public void setRoleManager(RoleManager roleManager) {
        this.roleManager = roleManager;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public MenuManager getMenuManager() {
        return menuManager;
    }

    public void setMenuManager(MenuManager menuManager) {
        this.menuManager = menuManager;
    }

    public FunctionManager getFunctionManager() {
        return functionManager;
    }

    public void setFunctionManager(FunctionManager functionManager) {
        this.functionManager = functionManager;
    }
}
